home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc / Developer Documentation / Recipes, Tech Notes & Articles / Tech Notes / Utilities Documentation / FocusLib < prev    next >
Encoding:
Text File  |  1995-11-06  |  6.2 KB  |  76 lines  |  [TEXT/ttxt]

  1. OpenDoc™ Utilities Documentation
  2.  
  3. FocusLib: Managing QuickDraw’s Drawing State
  4.  
  5. © 1993-1995  Apple Computer, Inc. All Rights Reserved.
  6. Apple, the Apple logo, and Macintosh are registered trademarks of Apple Computer, Inc.
  7. Mac and OpenDoc are trademarks of Apple Computer, Inc.
  8.  
  9.  
  10. Since OpenDoc does not define its own imaging model, MacOS-based OpenDoc parts will probably still be using QuickDraw or QuickDraw GX. Setting up the drawing environment to render into a facet takes a little bit of work. The QuickDraw GX case is discussed in the QuickDraw GX and OpenDoc recipe (in the Recipes: Imaging & Layout: folder.) Setting up the classic QuickDraw environment is a little harder, so we've written a utility to do the work for you: FocusLib. 
  11.  
  12. What FocusLib Does
  13.  
  14. FocusLib's name is unfortunate, since it is only dimly related to the regular OpenDoc concept of a focus. Its name comes from the Focus method in MacApp, which sets up QuickDraw to draw into a View.
  15.  
  16. Focusing does the following things:
  17. • Makes the facet's canvas the current GrafPort.
  18. • Moves the origin of the GrafPort to the origin of the frame's coordinate system, based on the internal and external transforms. In other words, (0,0) to QuickDraw is now the same place as (0,0) in your frame's coordinates.
  19. • Sets the clip region to the facet's clip shape, to prevent you from drawing outside of the facet.
  20.  
  21. Once you're focused, you can start issuing QuickDraw commands (or higher level things that use QuickDraw) using your frame's coordinate system.
  22.  
  23. What FocusLib Doesn’t Do
  24.  
  25. FocusLib sets up the QuickDraw environment, so it cannot set up any kind of drawing state or transforms that QuickDraw does not understand. In particular, it does not handle any type of transforms other than offsets. If your facet ends up scaled, rotated, skewed, etc., FocusLib will help you only with the offset portion of the transform. You can do the rest of the transformation manually by transforming the coordinates of all points before you draw them. (Transformations other than scales are particularly hard to handle in QuickDraw, which provides no native facilities for rotating text, bitmaps, ellipses...)
  26.  
  27. QuickDraw GX handles all kinds of transformations automatically, by the way.
  28.  
  29. Using FocusLib From C++
  30.  
  31. Using FocusLib is easy. The usual way, for C++ clients, is to declare a CFocus object on the stack. When the object is constructed, the focusing takes place. When the object goes out of scope and is destructed, the previous state of QuickDraw is restored. Example:
  32.     void DrawMyStuff( Environment *ev, ODFacet *facet ) {
  33.         CFocus foc(ev,facet);    // declares the CFocus object & sets up QuickDraw
  34.         MoveTo(0,0);
  35.         LineTo(100,100);
  36.     }                            // QuickDraw state is restored when the 'foc' object goes away
  37.  
  38. There are three variants of CFocus:
  39.  
  40. CFocusWindow sets the window, not the facet's canvas, as the current grafPort. There is no difference, unless your facet is on an offscreen canvas. In that case, a regular CFocus would not cause the drawing to appear immediately on screen since it would first go into the offscreen canvas until the next update event. For interactive use such as rubber-banding a line or object while the mouse is down, use CFocusWindow to ensure that things are drawn immediately to the screen.
  41.  
  42. CFocusFrame does not take into account the frame's internal transform. This means that (0,0) will be the top-left corner of the facet. This is useful when drawing frame adornments like borders or scrollbars instead of the actual contents.
  43.  
  44. CFocusWindowFrame is a combination of CFocusWindow and CFocusFrame.
  45.  
  46. The constructors of any of the CFocus classes take an optional extra parameter: this is a pointer to an ODShape. If it is supplied, drawing will be further clipped to the intersection of that shape and the facet's clipShape. This is useful when drawing into only part of the facet (as when handling a Draw message.)
  47.  
  48. Using FocusLib From C
  49.  
  50. If you are using C, or are very, very paranoid about C++ features like constructors, you can explicitly call BeginFocus and EndFocus. Example:
  51.     void DrawMyStuff( Environment *ev, ODFacet *facet ) {
  52.         FocusState state;
  53.         BeginFocus(ev,&state,facet,kODTrue,kODFalse,kODNULL);
  54.         MoveTo(0,0);
  55.         LineTo(100,100);
  56.         EndFocus(&state);        // Must explicitly end focusing!
  57.     }
  58.  
  59. You must declare a FocusState variable and then call BeginFocus, whose parameters look like this:
  60.  
  61.     void BeginFocus( Environment *ev, FocusState*, ODFacet*,
  62.                      ODBoolean toContent, ODBoolean toWindow, ODShape *clipTo );
  63.  
  64. The toContent parameter determines whether to clip to the frame's content (as in CFocus) or to the frame border (as in CFocusFrame).
  65. The toWindow parameter determines whether to draw directly into the window (as in CFocus) or into the facet's canvas (as in CFocusWindow).
  66. The clipTo parameter, if not kODNULL, is an ODShape to which drawing will be clipped.
  67.  
  68. It is important that you always call EndFocus after BeginFocus. If not, the drawing state will not be restored and you will leak some memory. If you use exceptions, and anything between BeginFocus and EndFocus could throw an exception, you need to catch the exception and call EndFocus before re-raising it. (The C++ classes are based on Destructos, so they always clean up automatically.)
  69.  
  70. PostScript Printing
  71.  
  72. FocusLib takes care of some tricky situations in PostScript printing. The LaserWriter driver does not handle Regions, so any attempt to clip to a nonrectangular area will be ignored in the PostScript output. This is bad news, since facets are often clipped to nonrectangular areas.
  73.  
  74. To work around this, FocusLib includes two utility functions that emit some fancy PostScript code to set the clipping properly. If you are using the FocusLib calls described above, these are called automatically and you don't need to worry about them. You only need to know about these calls if for some reason you do not want to use the rest of FocusLib!
  75.  
  76. ODBeginPostScriptClip emits PostScript code to clip to the ODShape passed in (in coordinate system of the current GrafPort.) ODEndPostScriptClip ends the clipping. These will have no effect unless the current GrafPort is in fact a printing port that is printing via the LaserWriter driver.